#include "include.h"
#include "bsp_eq.h"

#define EQ_CRC_SEED                             0xffff
#define EQ_BAND_NUM                             12
#define CAL_FIX(x)		                        ((int)(x * (1 << 27)))

uint calc_crc(void *buf, uint len, uint seed);
int eq_huart_putcs(uint8_t *packet, uint16_t len);
void huart_eq_init(u8 *rx_buf, uint rx_len);
void huart_rx_kick(void);
void music_set_soft_eq(u8 band_cnt,const u32 *eq_coef);
void music_set_soft_eq_dual(u8 lr,u8 band_cnt,const u32 *eq_coef);
void soft_eq_update_band(u8 band,const u32 *eq_coef);
extern const eq_param music_eq_tbl[MUSIC_EQ_TBL_LEN];
void drc_set_param_lp(const u32 *tbl);
void drc_set_param_hp(const u32 *tbl);
void music_set_soft_eq_lp(const u32 *eq_coef);
void music_set_soft_eq_hp(const u32 *eq_coef);
AT(.text.music)
void music_set_eq_by_num(u8 num)
{
    if (num > (MUSIC_EQ_TBL_LEN - 1)) {
        return;
    }
    if (music_set_eq_is_done()) {
        return;
    }
    sys_cb.eq_mode_set = 0;
    printf("set_eq_by_res: %d\n",num);
    #if DAC_SOFT_EQ_EN
        #if DAC_SOFT_EQ_DUAL_EN
        music_set_soft_eq_dual_by_res(0,music_eq_tbl[num].addr, music_eq_tbl[num].len);
        music_set_soft_eq_dual_by_res(1,music_eq_tbl[num].addr, music_eq_tbl[num].len);
        #else
        music_set_soft_eq_by_res(music_eq_tbl[num].addr, music_eq_tbl[num].len);
        #endif
    #else
        music_set_eq_by_res(music_eq_tbl[num].addr, music_eq_tbl[num].len);
    #endif
}

u8 eq_rx_buf[EQ_BUFFER_LEN];
#if EQ_MODE_EN

AT(.text.music)
void sys_set_eq(void)
{
    sys_cb.eq_mode++;
    if (sys_cb.eq_mode > 5) {
        sys_cb.eq_mode = 0;
    }
    music_set_eq_by_num(sys_cb.eq_mode);
    gui_box_show_eq();
#if BT_APP_EN
    bsp_app_audio_ctl(CMD_MSC_EQ_TYPE, sys_cb.eq_mode);
#endif
}
#endif // EQ_MODE_EN

#if EQ_DBG_IN_UART || EQ_DBG_IN_SPP
eq_dbg_cb_t eq_dbg_cb;
static u8 eq_tx_buf[12];
//const char tbl_eq_header[4] = "EQ0#";
const char tbl_eq_version[10] = {'E', 'Q', '0', '*', 6, 0, 12, 4, 5, 0};
const char tbl_drc_version[10] = {'D', 'R', '0', '*', 6, 0, 2, 0, 0, 0};

static void tx_ack(uint8_t *packet, uint16_t len)
{
    delay_5ms(1);   //延时一段时间再ack
    if (eq_dbg_cb.rx_type) {
#if EQ_DBG_IN_UART
        eq_huart_putcs(packet, len);
#endif // EQ_DBG_IN_UART
    } else {
#if EQ_DBG_IN_SPP && BT_SPP_EN
        if (xcfg_cb.eq_dgb_spp_en && (bt_get_status() >= BT_STA_CONNECTED)) {
            bt_spp_tx(packet, len);
        }
#endif // EQ_DBG_IN_SPP
    }
    eq_dbg_cb.rx_type = 0;
}

void eq_tx_ack(u8 bank_num, u8 ack)
{
    if (eq_dbg_cb.type) {
        eq_tx_buf[0] = 'D';
    } else {
        eq_tx_buf[0] = 'A';
    }
    eq_tx_buf[1] = bank_num;
    eq_tx_buf[2] = ack;
    eq_tx_buf[3] = -(eq_tx_buf[0] + eq_tx_buf[1] + eq_tx_buf[2]);
    tx_ack(eq_tx_buf, 4);
}

void eq_tx_version(void)
{
//    eq_tx_buf[0] = 'E';
//    eq_tx_buf[1] = 'Q';
//    eq_tx_buf[2] = '0';
//    eq_tx_buf[3] = '*';
//    eq_tx_buf[4] = 6;     //size
//    eq_tx_buf[5] = 0;
//    eq_tx_buf[6] = 12;    //band_cnt
//    eq_tx_buf[7] = 4;     //param size
//    eq_tx_buf[8] = 5;     //param cnt
//    eq_tx_buf[9] = 0;     //rsvd

    if (eq_dbg_cb.type) {
        memcpy(eq_tx_buf, tbl_drc_version, 10);
    } else {
        memcpy(eq_tx_buf, tbl_eq_version, 10);
    }
#if DAC_XDRC_EN
    eq_tx_buf[9] |= BIT(0);
#endif
    u16 crc = calc_crc(eq_tx_buf, 10, EQ_CRC_SEED);
    eq_tx_buf[10] = crc;
    eq_tx_buf[11] = crc >> 8;
    tx_ack(eq_tx_buf, 12);
}

#if DAC_XDRC_EN
enum{
XDRC_NULL = 0,
XDRC_ALL_EQ = 1,
XDRC_LP_EQ,
XDRC_HP_EQ,
XDRC_LP_DRC,
XDRC_HP_DRC,
XDRC_ALL_DRC,
XDRC_MAX_RES_NUM,
};

static const char xdrc_res_name[XDRC_MAX_RES_NUM][8] = {
    "NULL",
    "ALL.EQ",
    "LP.EQ",
    "HP.EQ",
    "LP.DRC",
    "HP.DRC",
    "ALL.DRC",
};

void xdrc_cmd_process(void)
{
    u8 band_cnt;
    switch (eq_dbg_cb.xdrc_res) {
    case XDRC_ALL_EQ:
        printf("XDRC_ALL_EQ:\n");
        band_cnt = eq_rx_buf[7];
        music_set_soft_eq(band_cnt,(u32 *)&eq_rx_buf[14]);
        break;

    case XDRC_LP_EQ:
        printf("XDRC_LP_EQ:\n");
        music_set_soft_eq_lp((u32 *)&eq_rx_buf[14]);
        break;
    case XDRC_HP_EQ:
        printf("XDRC_HP_EQ:\n");
        music_set_soft_eq_hp((u32 *)&eq_rx_buf[14]);
        break;

    case XDRC_LP_DRC:
        printf("XDRC_LP_DRC:\n");
        drc_set_param_lp(((u32*)&eq_rx_buf[10]));
        break;
    case XDRC_HP_DRC:
        printf("XDRC_HP_DRC:\n");
        drc_set_param_hp((u32 *)&eq_rx_buf[10]);
        break;
    case XDRC_ALL_DRC:
        printf("XDRC_HP_DRC:\n");
        drc_set_param((u32*)&eq_rx_buf[10]);
        break;
    }
}
#endif

#if SOFT_HARDWARE_EQ_DRC_EN
u8 hardware_eq_num = 0;
u8 get_hardware_eq_num(void)
{
    return SOFT_HARDWARE_EQ_DRC_EN*(hardware_eq_num);
}
#endif
void eq_parse_cmd(void)
{
    if (eq_rx_buf[0] == 'E' && eq_rx_buf[1] == 'Q') {
        eq_dbg_cb.type = 0;
    } else if (eq_rx_buf[0] == 'D' && eq_rx_buf[1] == 'R') {
        eq_dbg_cb.type = 1;
    } else {
        return;
    }
    if (eq_rx_buf[2] == '?' && eq_rx_buf[3] == '#') {
        eq_tx_version();
        return;
#if DAC_XDRC_EN
    } else if (eq_rx_buf[2] == '0' && eq_rx_buf[3] == ':') {
        //printf("-->%s\n",(char *)&eq_rx_buf[6]);
        eq_dbg_cb.xdrc_res = XDRC_MAX_RES_NUM;
        const char (*eq_name)[8];
        eq_name = xdrc_res_name;
        for (int i = 0; i < XDRC_MAX_RES_NUM; i++) {
            if (strcmp(eq_name[i], (char *)&eq_rx_buf[6]) == 0) {
                eq_dbg_cb.xdrc_res = i;
                break;
            }
        }
        //printf("eq_dbg_cb.xdrc_res = %d\n",eq_dbg_cb.xdrc_res);
        if (eq_dbg_cb.xdrc_res &&(eq_dbg_cb.xdrc_res < XDRC_MAX_RES_NUM)) {
            eq_tx_ack(0, 0);
        } else {
            eq_tx_ack(0, 1);
        }
        return;
#endif
    }
    //print_r(eq_rx_buf, EQ_BUFFER_LEN);
    u8 band_num = eq_rx_buf[6];
    u32 size = little_endian_read_16(eq_rx_buf, 4);
    u32 crc = calc_crc(eq_rx_buf, size+4, EQ_CRC_SEED);
    if (crc == little_endian_read_16(eq_rx_buf, 4+size)) {
        //printf("recv crc ok\n");
        eq_tx_ack(band_num, 0);
    } else {
        //printf("recv crc fail\n");
        eq_tx_ack(band_num, 1);
        return;
    }


#if BT_TWS_EN
//    tws_send_eq_param(eq_rx_buf, size + 6);
#endif

#if DAC_XDRC_EN
    xdrc_cmd_process();
    eq_dbg_cb.xdrc_res = XDRC_NULL;
    memset(eq_rx_buf, 0, EQ_BUFFER_LEN);
    return;
#endif
    if (eq_dbg_cb.type == 0) {
        u8 band_cnt = eq_rx_buf[7];
#if  DAC_SOFT_EQ_EN
    #if SOFT_HARDWARE_EQ_DRC_EN
        u8 soft_eq_num = (band_cnt > DAC_SOFT_EQ_NUM) ? DAC_SOFT_EQ_NUM : band_cnt;
//        my_printf("soft_eq_num:%d\n", soft_eq_num);

        hardware_eq_num = ((band_cnt - soft_eq_num) > 0) ? (band_cnt - soft_eq_num) : 0;
        if (hardware_eq_num > (SOFT_HARDWARE_EQ_NUM & 0x0f)) {
            hardware_eq_num = (SOFT_HARDWARE_EQ_NUM & 0x0f);
        }
//            my_printf("hardware_eq_num:%d\n", hardware_eq_num);
        if (hardware_eq_num) {
            music_set_eq(band_cnt, (u32 *)&eq_rx_buf[14]);      //硬件EQ在线调试,最大支持10段
        }

        delay_5ms(1);
        music_set_soft_eq(soft_eq_num,(u32 *)&eq_rx_buf[14]);  //软件EQ在线调试

    #else
        music_set_soft_eq(band_cnt,(u32 *)&eq_rx_buf[14]);  //软件EQ在线调试
    #endif
#else
        music_set_eq(band_cnt, (u32 *)&eq_rx_buf[14]);      //硬件EQ在线调试,最大支持10段
#endif
#if (UART0_PRINTF_SEL != PRINTF_NONE)
        printf("\nrecv eq data:\n");
        printf("%08x\n", little_endian_read_32(eq_rx_buf, 14));
        u8 k;
        u32 *ptr = (u32 *)&eq_rx_buf[18];
        for (k = 0; k < band_cnt*5; k++) {
            printf("%08x", *ptr++);
            if (k % 5 == 4) {
                printf("\n");
            } else {
                printf(" ");
            }
        }
#endif
    } else {
        drc_set_param((u32 *)&eq_rx_buf[10]);
#if (UART0_PRINTF_SEL != PRINTF_NONE)
//        printf("\nrecv drc data:\n");
//        u32 *ptr = (u32 *)&eq_rx_buf[10];
//        for (int i = 0; i < 10; i++) {
//            printf("%08x\n", ptr[i]);
//        }
//        printf("\n");
#endif
    }
    memset(eq_rx_buf, 0, EQ_BUFFER_LEN);
}

#if EQ_DBG_IN_UART
AT(.com_text.eq)
void huart_rx_done(void)
{
    msg_enqueue(EVT_ONLINE_SET_EQ);
    eq_dbg_cb.rx_type = 1;
}

AT(.com_text.eq)
void huart_rx_set_dir(void)
{
    if (xcfg_cb.eq_uart_sel == 0) {
        GPIOADIR |= BIT(7);
    } else if (xcfg_cb.eq_uart_sel == 1) {
        GPIOBDIR |= BIT(2);
    } else if (xcfg_cb.eq_uart_sel == 2) {
        GPIOBDIR |= BIT(3);
    }
}

AT(.com_text.eq)
void huart_tx_set_dir(void)
{
    if (xcfg_cb.eq_uart_sel == 0) {
        GPIOADIR &= ~BIT(7);
    } else if (xcfg_cb.eq_uart_sel == 1) {
        GPIOBDIR &= ~BIT(2);
    } else if (xcfg_cb.eq_uart_sel == 2) {
        GPIOBDIR &= ~BIT(3);
    }
}

void eq_dbg_huart_init(void)
{
    FUNCMCON0 = 0x0f << 20 | 0x0f << 16;
    if (xcfg_cb.eq_uart_sel == 0) {
        if (UART0_PRINTF_SEL == PRINTF_PA7) {
            FUNCMCON0 = 0x0f << 8;
        }
        FUNCMCON0 = 0x01 << 20 | 0x01 << 16;
        GPIOADE |= BIT(7);
        GPIOAFEN |= BIT(7);
    } else if (xcfg_cb.eq_uart_sel == 1) {
        if (UART0_PRINTF_SEL == PRINTF_PB2) {
            FUNCMCON0 = 0x0f << 8;
        }
        FUNCMCON0 = 0x02 << 20 | 0x02 << 16;
        GPIOBDE |= BIT(2);
        GPIOBFEN |= BIT(2);
    } else if (xcfg_cb.eq_uart_sel == 2) {
        if (UART0_PRINTF_SEL == PRINTF_PB3) {
            FUNCMCON0 = 0x0f << 8;
        }
        FUNCMCON0 = 0x03 << 20 | 0x03 << 16;
        GPIOBDE |= BIT(3);
        GPIOBFEN |= BIT(3);
    }
    huart_eq_init(eq_rx_buf, EQ_BUFFER_LEN);
    huart_rx_set_dir();
    huart_rx_kick();
}
#endif

void eq_dbg_init(void)
{
    memset(eq_rx_buf, 0, EQ_BUFFER_LEN);
    memset(&eq_dbg_cb, 0, sizeof(eq_dbg_cb_t));
#if EQ_DBG_IN_UART
    if (xcfg_cb.eq_dgb_uart_en) {
        eq_dbg_huart_init();
    }
#endif // EQ_DBG_IN_UART

}
#endif

#if !EQ_DBG_IN_UART
void huart_rx_done(void) {}
void huart_rx_set_dir(void) {}
void huart_tx_set_dir(void) {}
#endif


static u32 * music_bass_coef = NULL;
static u32 * music_treble_coef = NULL;
static u32 * music_lowhigh_pass_coef = NULL;
static u32 * music_lowhigh_pass_coef_extend = NULL;
static u32 * music_bassboost_coef = NULL;

void music_bass_coef_set(u32 * coef)
{
    music_bass_coef = coef;
}

void music_treble_coef_set(u32 * coef)
{
    music_treble_coef = coef;
}

void music_lowhigh_pass_coef_set(u32 * coef)
{
    music_lowhigh_pass_coef = coef;
}
void music_lowhigh_pass_ext_coef_set(u32 * coef)
{
    music_lowhigh_pass_coef_extend = coef;
}

void music_bassboost_coef_set(u32 * coef)
{
    music_bassboost_coef = coef;
}

u8 lowhigh_pass_bass_en(void)
{
    return (0x10*LOWHIGH_PASS_FDSLOPE_24DB) | LOWPASS_BASSBOOST_PHASE180_EN;//24DB/OTC复用第8、9段EQ实现
}
void wait_eq_set_done(void)  //等待EQ设置完成.
{
    u32 ticks = tick_get();
    while(music_set_eq_is_done()) {
        if (tick_check_expire(ticks, 30)){
            break;
        }
    }
    //printf("---->diff ticks = %d\n",tick_get() - ticks);
}


//库调用低音参数
const u32 *music_eq_get_bass_tbl(void)
{
    return music_bass_coef;
}

//库调用高音参数
const u32 *music_eq_get_treble_tbl(void)
{
    return music_treble_coef;
}

//库调用高通低通参数
const u32 *music_eq_get_low_high_pass_tbl(void)//low\high pass复用第9段EQ实现
{
    return music_lowhigh_pass_coef;
}

//库调用bassboost参数
const u32 *music_eq_get_bassboost_tbl(void)     //bassboost复用第10段EQ实现
{
    return music_bassboost_coef;
}

const u32 *music_eq_get_low_high_pass_tbl_extend(void)
{
    return music_lowhigh_pass_coef_extend;
}

#if MIC_EQ_FOR_IDX_EN
const int tbl_coef_mic_1[6] = {
	CAL_FIX(0.9999557883),    //Band:0(66.000Hz)
	CAL_FIX(0.9995940400),    //Band:1(200.000Hz)
	CAL_FIX(0.9963483378),    //Band:2(600.000Hz)
	CAL_FIX(0.9898674722),    //Band:3(1000.000Hz)
	CAL_FIX(0.9596752251),    //Band:4(2000.000Hz)
	CAL_FIX(0.6563277892),    //Band:5(6000.000Hz)
};

//Q:0.750000
const int tbl_coef_mic_0[6] = {
	CAL_FIX(0.0062688455),    //Band:0(66.000Hz)
	CAL_FIX(0.0189942108),    //Band:1(200.000Hz)
	CAL_FIX(0.0569209578),    //Band:2(600.000Hz)
	CAL_FIX(0.0946628813),    //Band:3(1000.000Hz)
	CAL_FIX(0.1874074140),    //Band:4(2000.000Hz)
	CAL_FIX(0.5029839110),    //Band:5(6000.000Hz)
};
#endif

#if SYS_BASS_TREBLE_EN || SYS_EQ_FOR_IDX_EN || DAC_SOFT_EQ_DUAL_EN
#if DAC_SOFT_EQ_DUAL_EN
const int tbl_coef_1[10] = {   //使用ABTOOL改变bass/treb频率，music一共有10条band， 如果有loud/bass/eq,其中7用于loud, 8/9条用于bass/treb
	CAL_FIX(0.9974636515),    //Band:0(500Hz)
	CAL_FIX(0.9898674722),    //Band:1(1000Hz)
	CAL_FIX(0.9772499952),    //Band:2(1500Hz)
	CAL_FIX(0.9596752251),    //Band:3(2000Hz)
	CAL_FIX(0.9372323134),    //Band:4(2500Hz)
	CAL_FIX(0.9100351062),    //Band:5(3000Hz)
	CAL_FIX(0.8782215667),    //Band:6(3500Hz)
	CAL_FIX(0.8419530754),    //Band:7(4000Hz)

    CAL_FIX(0.9990866674),    //BASS:300Hz
    CAL_FIX(0.9100351062),    //TREB:3000Hz
};

//Q:0.750000
const int tbl_coef_0[10] = {
	CAL_FIX(0.0474517949),    //Band:0(500Hz)
	CAL_FIX(0.0946628813),    //Band:1(1000Hz)
	CAL_FIX(0.1413937715),    //Band:2(1500Hz)
	CAL_FIX(0.1874074140),    //Band:3(2000Hz)
	CAL_FIX(0.2324703954),    //Band:4(2500Hz)
	CAL_FIX(0.2763541250),    //Band:5(3000Hz)
	CAL_FIX(0.3188359939),    //Band:6(3500Hz)
	CAL_FIX(0.3597005044),    //Band:7(4000Hz)

    CAL_FIX(0.0284864965),    //BASS:300Hz
    CAL_FIX(0.2763541250),    //TREB:3000Hz

};
#else
const int tbl_coef_1[10] = {   //使用ABTOOL改变bass/treb频率，music一共有10条band， 如果有loud/bass/eq,其中7用于loud, 8/9条用于bass/treb
	CAL_FIX(0.9999902462),    //Band:0(31Hz)
	CAL_FIX(0.9999597162),    //Band:1(63Hz)
	CAL_FIX(0.9997401793),    //Band:2(160Hz)
	CAL_FIX(0.9983764898),    //Band:3(400Hz)
	CAL_FIX(0.9898674722),    //Band:4(1000Hz)
	CAL_FIX(0.8419530754),    //Band:5(4000Hz)
	CAL_FIX(0.4177699622),    //Band:6(8000Hz)
	CAL_FIX(-0.6509365173),   //Band:7(16000Hz)

    CAL_FIX(0.9990866674),    //BASS:300Hz
    CAL_FIX(0.9100351062),    //TREB:3000Hz
};

//Q:0.750000
const int tbl_coef_0[10] = {
	CAL_FIX(0.0029444916),    //Band:0(31Hz)
	CAL_FIX(0.0059839058),    //Band:1(63Hz)
	CAL_FIX(0.0151961090),    //Band:2(160Hz)
	CAL_FIX(0.0379729998),    //Band:3(400Hz)
	CAL_FIX(0.0946628813),    //Band:4(1000Hz)
	CAL_FIX(0.3597005044),    //Band:5(4000Hz)
	CAL_FIX(0.6057018917),    //Band:6(8000Hz)
	CAL_FIX(0.5060881129),    //Band:7(16000Hz)

    CAL_FIX(0.0284864965),    //BASS:300Hz
    CAL_FIX(0.2763541250),    //TREB:3000Hz
};
#endif

struct eq_coef_tbl_t bass_treb_coef_tbl = {
    .coef_0 = &tbl_coef_0[8],
    .coef_1 = &tbl_coef_1[8],
};

void *bass_treble_get_coef_tbl(void)  //bass_treble_coef_cal 计算bass/treb时会回调此函数，传入bass/treb的频率
{
    return &bass_treb_coef_tbl;
}

//customer bass[10,300]
const int tbl_coef_1_customer[30] = {
	CAL_FIX(0.9999989850),    //10Hz
	CAL_FIX(0.9999959401),    //20Hz
	CAL_FIX(0.9999908653),    //30Hz
	CAL_FIX(0.9999837605),    //40Hz
	CAL_FIX(0.9999746259),    //50Hz
	CAL_FIX(0.9999634614),    //60Hz
	CAL_FIX(0.9999502670),    //70Hz
	CAL_FIX(0.9999350427),    //80Hz
    CAL_FIX(0.9999177887),    //90Hz
    CAL_FIX(0.9998985049),    //100Hz
    CAL_FIX(0.9998771913),    //110Hz
	CAL_FIX(0.9998538481),    //120Hz
	CAL_FIX(0.9998284752),    //130Hz
	CAL_FIX(0.9998010728),    //140Hz
	CAL_FIX(0.9997716408),    //150Hz
	CAL_FIX(0.9997401793),    //160Hz
	CAL_FIX(0.9997066884),    //170Hz
	CAL_FIX(0.9996711682),    //180Hz
    CAL_FIX(0.9996336187),    //190Hz
    CAL_FIX(0.9995940400),    //200Hz
    CAL_FIX(0.9995524323),    //210Hz
	CAL_FIX(0.9995087954),    //220Hz
	CAL_FIX(0.9994631297),    //230Hz
	CAL_FIX(0.9994154351),    //240Hz
	CAL_FIX(0.9993657117),    //250Hz
	CAL_FIX(0.9993139597),    //260Hz
	CAL_FIX(0.9992601792),    //270Hz
	CAL_FIX(0.9992043702),    //280Hz
    CAL_FIX(0.9991465329),    //290Hz
    CAL_FIX(0.9990866674),    //300Hz
};

//Q:0.750000
const int tbl_coef_0_customer[30] = {
	CAL_FIX(0.0009498388),    //10Hz
	CAL_FIX(0.0018996756),    //20Hz
	CAL_FIX(0.0028495085),    //30Hz
	CAL_FIX(0.0037993357),    //40Hz
	CAL_FIX(0.0047491552),    //50Hz
	CAL_FIX(0.0056989650),    //60Hz
	CAL_FIX(0.0066487633),    //70Hz
	CAL_FIX(0.0075985481),    //80Hz
    CAL_FIX(0.0085483174),    //90Hz
    CAL_FIX(0.0094980694),    //100Hz
    CAL_FIX(0.0104478021),    //110Hz
	CAL_FIX(0.0113975136),    //120Hz
	CAL_FIX(0.0123472020),    //130Hz
	CAL_FIX(0.0132968653),    //140Hz
	CAL_FIX(0.0142465016),    //150Hz
	CAL_FIX(0.0151961090),    //160Hz
	CAL_FIX(0.0161456855),    //170Hz
	CAL_FIX(0.0170952293),    //180Hz
    CAL_FIX(0.0180447384),    //190Hz
    CAL_FIX(0.0189942108),    //200Hz
    CAL_FIX(0.0199436447),    //210Hz
	CAL_FIX(0.0208930381),    //220Hz
	CAL_FIX(0.0218423890),    //230Hz
	CAL_FIX(0.0227916957),    //240Hz
	CAL_FIX(0.0237409561),    //250Hz
	CAL_FIX(0.0246901683),    //260Hz
	CAL_FIX(0.0256393303),    //270Hz
	CAL_FIX(0.0265884403),    //280Hz
    CAL_FIX(0.0275374964),    //290Hz
    CAL_FIX(0.0284864965),    //300Hz
};

struct eq_coef_tbl_t bass_coef_tbl_customer[2];
#endif



#if SYS_BASS_TREBLE_EN
int music_coef[11];
//参数默认44.1kHz
void bsp_bass_treble_init(void)
{
    music_coef[0] = 0x800000;   //衰减0dB
    bass_treble_coef_cal(&music_coef[1], 0, 0);
    bass_treble_coef_cal(&music_coef[6], 0, 1);
    //只有高低音,不要EQ.  //调节时请调用 mic_bass_treble_set 只设置了高低音。
    //更改bass/treb频率请使用ABTOOL 改变第8/9段的频率，重新生成并替换 tbl_coef_0/tbl_coef_1表格。(0~7段参数无效，程序不会使用)
    //music_bass_coef_set(NULL);
    //music_treble_coef_set(NULL);

    //同时支持高低音和EQ   //调节时请调用 music_bass_treble_eq_set,设置高低音同时设置了EQ
    //更改bass/treb频率请使用ABTOOL 改变第8/9段的频率，重新生成并替换 tbl_coef_0/tbl_coef_1表格。(0~7段参数无效，程序使用的是Equalizer生成的EQ文件的0~7段参数)
    music_bass_coef_set((u32 *)&music_coef[1]);
    music_treble_coef_set((u32 *)&music_coef[6]);
}

//设置MUSIC高低音（会影响其他段EQ，不能边调EQ边调高低音）
void music_bass_treble_set(int mode, int gain)
{
    if (EQ_BASS == mode) {    //bass
        bass_treble_coef_cal(&music_coef[1], gain, 0);
    } else if (EQ_TREB == mode) {      //treble
        bass_treble_coef_cal(&music_coef[6], gain, 1);
    }
    music_set_eq(2, (u32 *)music_coef);

#if BT_APP_EN
    if (EQ_BASS == mode) {
        bsp_app_audio_ctl(CMD_MSC_BASS_VOL, gain + 12);
    } else if (EQ_TREB == mode) {
        bsp_app_audio_ctl(CMD_MSC_TREB_VOL, gain + 12);
    }
#endif
}

//设置MUSIC高低音（通过设置系统EQ来设置BASS和TREB，系统EQ不能为空)
//不会影响其他段EQ，适合又调EQ，又调高低音的用法）
void music_bass_treble_eq_set(int mode, int gain)    //gain [-24,+24]
{
#if (DAC_SOFT_EQ_EN) //软件EQ + 高低音 + DRC
    if (EQ_BASS == mode) {    //bass
        bass_treble_coef_cal(&music_coef[1], gain, 0);
        soft_eq_update_band((DAC_SOFT_EQ_NUM - 2),(const u32 *)&music_coef[1]);
    } else if (EQ_TREB == mode) {      //treble
        bass_treble_coef_cal(&music_coef[6], gain, 1);
        soft_eq_update_band((DAC_SOFT_EQ_NUM  - 1),(const u32 *)&music_coef[6]);
    }
#else //硬件EQ + 高低音
    if (EQ_BASS == mode) {    //bass
        bass_treble_coef_cal(&music_coef[1], gain, 0);
    } else if (EQ_TREB == mode) {      //treble
        bass_treble_coef_cal(&music_coef[6], gain, 1);
    }
    music_set_eq_by_num(sys_cb.eq_mode);
#endif
}

//自定义低音频点调节
//不会影响其他段EQ，适合又调EQ，又调低音的用法）
void music_bass_eq_set_customer(int gain,u8 freq)    //gain [-24,+24] freq [1,30]
{
    //printf("%s : %d , %d\n",__func__,gain,freq);
    bass_coef_tbl_customer->coef_0 = &tbl_coef_0_customer[freq - 1];
    bass_coef_tbl_customer->coef_1 = &tbl_coef_1_customer[freq - 1];
    bass_treble_coef_cal_freq(&music_coef[1], gain, 0,bass_coef_tbl_customer);
#if (DAC_SOFT_EQ_EN) //软件EQ + 高低音 + DRC
    soft_eq_update_band((DAC_SOFT_EQ_NUM - 2),(const u32 *)&music_coef[1]);
#else //硬件EQ + 高低音
    music_set_eq_by_num(sys_cb.eq_mode);
#endif
}
#endif


//10条EQ独立调节
#if SYS_EQ_FOR_IDX_EN || DAC_SOFT_EQ_DUAL_EN    //系统EQ不能为空
int eq_coef_l[50+1];       //10 条谱线, 每条谱线由5个int控制.
#if DAC_SOFT_EQ_DUAL_EN
int eq_coef_r[50+1];       //10 条谱线, 每条谱线由5个int控制.
#endif

struct eq_coef_tbl_t eq_coef_tbl = {
    .coef_0 = tbl_coef_0,
    .coef_1 = tbl_coef_1,
};

//库调用，EQ[0~7]条band独立调EQ, 8/9做高低音
const u32 *music_eq_get_tbl(u8 index)
{
    if (index < 8) {
        return (u32 *)&eq_coef_l[index * 5 + 1];
    } else {
        return NULL;
    }
}

//0~7独立调EQ, 8/9 做高低音。
//更改各谱线频率，请使用ABTOOL更改各谱线频率,重新生成并替换 tbl_coef_0/tbl_coef_1
void sys_eq_for_idx_init(void)
{
    printf("%s\n",__func__);
    eq_coef_l[0] = 0x800000;          //衰减0dB
#if DAC_SOFT_EQ_DUAL_EN
    eq_coef_r[0] = 0x800000;         //衰减0dB
#endif
    for (int i = 0; i < 10; i++) {
        if (i == 8) {           //bass
            bass_treble_coef_cal(&eq_coef_l[40 + 1], 0, 0);  //如果不调高低音，系数生成还是调用eq_coef_cal
        } else if (i == 9) {    //treble
            bass_treble_coef_cal(&eq_coef_l[45 + 1], 0, 1);  //如果不调高低音，系数生成还是调用eq_coef_cal
        } else {                //eq
            eq_coef_cal(i, &eq_coef_l[i * 5 + 1], 0, &eq_coef_tbl);
#if DAC_SOFT_EQ_DUAL_EN
            eq_coef_cal(i, &eq_coef_r[i * 5 + 1], 0, &eq_coef_tbl);
#endif
        }
    }
    music_bass_coef_set((u32 *)&eq_coef_l[40 + 1]);
    music_treble_coef_set((u32 *)&eq_coef_l[45 + 1]);
#if DAC_SOFT_EQ_DUAL_EN
    music_bass_coef_set((u32 *)&eq_coef_r[40 + 1]);
    music_treble_coef_set((u32 *)&eq_coef_r[45 + 1]);
#endif
}

//0~7独立调EQ, 8/9做高低音。
//更改各谱线频率，请使用ABTOOL更改各谱线频率,重新生成并替换 tbl_coef_0/tbl_coef_1
void music_set_eq_for_index(u8 index, int gain)
{
    if (index > 9 || gain < -24 || gain > 24) {
        return;
    }
    if (index == 8) {           //bass
        bass_treble_coef_cal(&eq_coef_l[40 + 1], gain, 0);  //如果不调高低音，系数生成还是调用eq_coef_cal
    } else if (index == 9) {    //treble
        bass_treble_coef_cal(&eq_coef_l[45 + 1], gain, 1);  //如果不调高低音，系数生成还是调用eq_coef_cal
    } else {                    //eq
        eq_coef_cal(index, &eq_coef_l[index * 5 + 1], gain, &eq_coef_tbl);
    }
#if (DAC_SOFT_EQ_EN) //软件EQ + 高低音 + DRC
    music_set_soft_eq(10, (u32 *)eq_coef_l);
#else
    music_set_eq(10, (u32 *)eq_coef_l);
#endif
}

#if DAC_SOFT_EQ_DUAL_EN
const u32 *music_eq_dual_get_tbl(u8 lr,u8 index)	//lr = 0 : left channel , lr = 1 : right channel
{
    if (index < 8) {
        if(lr){
            return (u32 *)&eq_coef_r[index * 5 + 1];
        }else{
            return (u32 *)&eq_coef_l[index * 5 + 1];
        }
    } else {
        return NULL;
    }
}

//0~7独立调EQ, 8/9做高低音。
//更改各谱线频率，请使用ABTOOL更改各谱线频率,重新生成并替换 tbl_coef_0/tbl_coef_1
void music_set_eq_dual_for_index(u8 lr,u8 index, int gain)
{
    if (index > 7 || gain < -24 || gain > 24) {
        return;
    }
    //printf("%s:%d,%d\n",__func__,index,gain);                 //eq
    if(lr){
        eq_coef_cal(index, &eq_coef_r[index * 5 + 1], gain, &eq_coef_tbl);
    }else{
        eq_coef_cal(index, &eq_coef_l[index * 5 + 1], gain, &eq_coef_tbl);
    }

    if(lr){
        music_set_soft_eq_dual(lr,8, (u32 *)eq_coef_r);
    }else{
        music_set_soft_eq_dual(lr,8, (u32 *)eq_coef_l);
    }
}
#endif
#endif

//MIC的6条EQ独立调节
#if MIC_EQ_FOR_IDX_EN        //系统EQ不能为空
int eq_coef_mic[30+1];       //6 条谱线, 每条谱线由5个int控制.

struct eq_coef_tbl_t eq_coef_mic_tbl = {
    .coef_0 = tbl_coef_mic_0,
    .coef_1 = tbl_coef_mic_1,
};

////库调用，EQ[0~5]条band独立调EQ
//const u32 *mic_eq_get_tbl(u8 index)
//{
//    if (index < 6) {
//        return (u32 *)&eq_coef_mic[index * 5 + 1];
//    } else {
//        return NULL;
//    }
//}

//0~5独立调EQ
//更改各谱线频率，请使用ABTOOL更改各谱线频率,重新生成并替换 tbl_coef_mic_0/tbl_coef_mic_1
void mic_eq_for_idx_init(void)
{
    printf("%s\n",__func__);
    eq_coef_mic[0] = 0x800000;          //衰减0dB

    for (int i = 0; i < 6; i++) {
        //6条谱线均是eq
        eq_coef_cal(i, &eq_coef_mic[i * 5 + 1], 0, &eq_coef_mic_tbl);
    }
}

//0~5独立调EQ
//更改各谱线频率，请使用ABTOOL更改各谱线频率,重新生成并替换 tbl_coef_mic_0/tbl_coef_mic_1
void mic_set_eq_for_index(u8 index, int gain)
{
//    my_printf("%s: index:%d gain:%d\n", __func__, index, gain);

    if (index > 5 || gain < -24 || gain > 24) {
        return;
    }
    //6条谱线均是eq
    eq_coef_cal(index, &eq_coef_mic[index * 5 + 1], gain, &eq_coef_mic_tbl);

    mic_set_eq(6, (u32 *)eq_coef_mic);
}
#endif

#if MIC_LOUD_EN

static u32 * mic_loud_coef = NULL;
static int eqloud_coef[6];

const int mic_loud_tbl_coef_1[1] = {   //使用ABTOOL改变loud/bass/treb频率，MIC一共有6条band，其中3/4/5条用于loud/bass/treb
    CAL_FIX(0.9935112308),    //Band:3(800.000Hz)
};

//Q:0.750000
const int mic_loud_tbl_coef_0[1] = {
	CAL_FIX(0.0758227005),    //Band:3(800.000Hz)
};

struct eq_coef_tbl_t mic_loud_coef_tbl = {
    .coef_0 = &mic_loud_tbl_coef_0[0],
    .coef_1 = &mic_loud_tbl_coef_1[0],
};

void mic_loud_coef_set(u32 * coef)
{
    mic_loud_coef = coef;
}

//库调用，把MIC EQ的Band 3 当作中音，返回NULL，则采用资源的EQ表
const u32 *mic_eq_get_loud_tbl(void)
{
    return mic_loud_coef;
}

void mic_eq_loud_init(void)
{
    eqloud_coef[0] = 0x800000;     //衰减0dB
    eq_coef_cal(0, &eqloud_coef[1], 0, &mic_loud_coef_tbl);
    mic_loud_coef_set((u32*)&eqloud_coef[1]);
}

//设置MIC中音
void mic_eq_loud_set(int gain)  //gain [-24,24]
{
    if (gain < -24 || gain > 24) {
        return;
    }
    eq_coef_cal(0, &eqloud_coef[1], gain, &mic_loud_coef_tbl);
    mic_set_eq(1, (u32 *)eqloud_coef);  //只调中音
    //mic_set_eq_by_res(&RES_BUF_EQ_MIC_NORMAL_EQ, &RES_LEN_EQ_MIC_NORMAL_EQ);  //支持EQ，同时也支持中音
}
#endif // MIC_LOUD_EN


#if MIC_BASS_TREBLE_EN

static u32 * mic_bass_coef = NULL;
static u32 * mic_treble_coef = NULL;
static int mic_coef[11];

const int mic_bass_treb_tbl_coef_1[2] = {   //使用ABTOOL改变bass/treb频率，MIC一共有6条band，其中4/5条用于bass/treb
//	CAL_FIX(0.9997716408),    //Band:4(150.000Hz)
//	CAL_FIX(0.9935112308),    //Band:5(800.000Hz)

    CAL_FIX(0.9974636515),    //Band:4(500.000Hz)
	CAL_FIX(0.9596752251),    //Band:5(2000.000Hz)
};

//Q:0.750000
const int mic_bass_treb_tbl_coef_0[2] = {
//	CAL_FIX(0.0142465016),    //Band:4(150.000Hz)
//	CAL_FIX(0.0758227005),    //Band:5(800.000Hz)
	CAL_FIX(0.0474517949),    //Band:4(500.000Hz)
	CAL_FIX(0.1874074140),    //Band:5(2000.000Hz)
};

struct eq_coef_tbl_t mic_bass_treb_coef_tbl = {
    .coef_0 = &mic_bass_treb_tbl_coef_0[0],
    .coef_1 = &mic_bass_treb_tbl_coef_1[0],
};

void mic_bass_coef_set(u32 * coef)
{
    mic_bass_coef = coef;
}

void mic_treble_coef_set(u32 * coef)
{
    mic_treble_coef = coef;
}

//库调用，把MIC EQ的Band 4 当作低音，返回NULL，则采用资源的EQ表
const u32 *mic_eq_get_bass_tbl(void)
{
    return mic_bass_coef;
}

//库调用，把MIC EQ的Band 5当作高音，返回NULL，则采用资源的EQ表
const u32 *mic_eq_get_treble_tbl(void)
{
    return mic_treble_coef;
}

void mic_bass_treble_init(void)
{
    mic_coef[0] = 0x800000;     //衰减0dB
    bass_treble_coef_cal_freq(&mic_coef[1], 0, 0,&mic_bass_treb_coef_tbl);
    bass_treble_coef_cal_freq(&mic_coef[6], 0, 1,&mic_bass_treb_coef_tbl);
    mic_bass_coef_set((u32*)&mic_coef[1]);
    mic_treble_coef_set((u32*)&mic_coef[6]);
}

//设置MIC高低音
void mic_bass_treble_set(int mode, int gain)  //mode: 0_bass, 1_treb //gain [-24,24]
{
    if (EQ_BASS == mode) {    //bass
        bass_treble_coef_cal_freq(&mic_coef[1], gain, 0, &mic_bass_treb_coef_tbl);
    } else if (EQ_TREB == mode) {      //treble
        bass_treble_coef_cal_freq(&mic_coef[6], gain, 1, &mic_bass_treb_coef_tbl);
    }
    mic_set_eq(2, (u32 *)mic_coef);  //只调高低音
    //mic_set_eq_by_res(&RES_BUF_EQ_MIC_NORMAL_EQ, &RES_LEN_EQ_MIC_NORMAL_EQ);  //支持EQ，同时也支持高低音
}

/*
//测试代码
void mic_tre_bass_up(void);
void mic_tre_bass_down(void);
static int mic_tre_bass = 0;
void mic_tre_bass_up(void)
{
    if (++mic_tre_bass > 12) {
        mic_tre_bass = 12;
    }
    printf("mic_tre_bass = %d\n",mic_tre_bass);
    mic_bass_treble_set(0,mic_tre_bass);
    //mic_bass_treble_set(1,mic_tre_bass);
}

void mic_tre_bass_down(void)
{
    if (--mic_tre_bass < -12) {
        mic_tre_bass = -12;
    }
    printf("mic_tre_bass = %d\n",mic_tre_bass);
    mic_bass_treble_set(0,mic_tre_bass);
    //mic_bass_treble_set(1,mic_tre_bass);
}
*/
#endif


#if AUCAR_EQ_LOUD_BASS_TREBLE_EN
//使用ABTOOL改变loud/bass/treb频率，music一共有10条band，其中7用于loud, 8/9条用于bass/treb
//(0~6段参数无效，程序EQ使用的是Equalizer生成的EQ文件的0~6段参数)
//前7条谱线用于EQ调节.
const int tbl_coef_aucar_1[10] = {
        CAL_FIX(0.9999902462),    //Band:0(31Hz)
        CAL_FIX(0.9999597162),    //Band:1(63Hz)
        CAL_FIX(0.9997401793),    //Band:2(160Hz)
        CAL_FIX(0.9983764898),    //Band:3(400Hz)
        CAL_FIX(0.9898674722),    //Band:4(1000Hz)
        CAL_FIX(0.8419530754),    //Band:5(4000Hz)
        CAL_FIX(0.4177699622),    //Band:6(8000Hz)
        CAL_FIX(0.9998985049),    //LOUD:7(100Hz)
        CAL_FIX(0.9990866674),    //BASS:300Hz
        CAL_FIX(0.9100351062),    //TREB:3000Hz
};

//Q:0.750000
const int tbl_coef_aucar_0[10] = {
        CAL_FIX(0.0029444916),    //Band:0(31Hz)
        CAL_FIX(0.0059839058),    //Band:1(63Hz)
        CAL_FIX(0.0151961090),    //Band:2(160Hz)
        CAL_FIX(0.0379729998),    //Band:3(400Hz)
        CAL_FIX(0.0946628813),    //Band:4(1000Hz)
        CAL_FIX(0.3597005044),    //Band:5(4000Hz)
        CAL_FIX(0.6057018917),    //Band:6(8000Hz)
        CAL_FIX(0.0094980694),    //LOUD:7(100Hz)
        CAL_FIX(0.0284864965),    //BASS:300Hz
        CAL_FIX(0.2763541250),    //TREB:3000Hz
};

static int eq_coef_aucar[50+1];       //10 条谱线, 每条谱线由5个int控制.
struct eq_coef_tbl_t eq_coef_tbl_aucar = {
    .coef_0 = tbl_coef_aucar_0,
    .coef_1 = tbl_coef_aucar_1,
};

struct eq_coef_tbl_t eq_coef_tbl_aucar_bass_treb = {
    .coef_0 = &tbl_coef_aucar_0[8],
    .coef_1 = &tbl_coef_aucar_1[8],
};

//更改loud/bass/tre频率请使用ABTOOL 改变第7/8/9段的频率，重新生成并替换 tbl_coef_aucar_0/tbl_coef_aucar_1表格。
void aucar_eq_loud_bass_tre_init(void)
{
    eq_coef_aucar[0] = 0x800000;          //衰减0dB
    for (int i = 0; i < 10; i++) {
        if (i == 8) {           //bass
            bass_treble_coef_cal_freq(&eq_coef_aucar[40 + 1], 0, 0,&eq_coef_tbl_aucar_bass_treb);
        } else if (i == 9) {    //treble
            bass_treble_coef_cal_freq(&eq_coef_aucar[45 + 1], 0, 1,&eq_coef_tbl_aucar_bass_treb);
        } else {                    //eq
            eq_coef_cal(i, &eq_coef_aucar[i * 5 + 1], 0, &eq_coef_tbl_aucar);
        }
    }
    music_bass_coef_set((u32 *)&eq_coef_aucar[40 + 1]);
    music_treble_coef_set((u32 *)&eq_coef_aucar[45 + 1]);
}

void music_set_eq_for_aucar(u8 index, int gain)
{
    if (index > 9 || gain < -24 || gain > 24) {
        return;
    }
    if (index == 8) {           //bass
        bass_treble_coef_cal_freq(&eq_coef_aucar[40 + 1], gain, 0,&eq_coef_tbl_aucar_bass_treb);  //5*8 = 40
    } else if (index == 9) {    //treble
        bass_treble_coef_cal_freq(&eq_coef_aucar[45 + 1], gain, 1,&eq_coef_tbl_aucar_bass_treb);  //5*9 = 45
    } else {                    //eq
        eq_coef_cal(index, &eq_coef_aucar[index * 5 + 1], gain, &eq_coef_tbl_aucar);
    }
}

//库回调，第7条, 单独EQ用于loud
const u32 *music_eq_get_tbl(u8 index)
{
	if (index == 7) {  //第7条, 单独EQ
        return (u32 *)&eq_coef_aucar[index * 5 + 1];
    } else {
        return NULL;
    }
}

//更改loud/bass/tre频率请使用ABTOOL 改变第7/8/9段的频率，重新生成并替换 tbl_coef_aucar_0/tbl_coef_aucar_1表格。(0~6段参数无效，程序EQ使用的是Equalizer生成的EQ文件的0~6段参数)
void aucar_music_loud_set(int gain)  //LOUD
{
    wait_eq_set_done();
    music_set_eq_for_aucar(7, gain);
    music_set_eq_by_num(sys_cb.eq_mode);
}
void aucar_music_bass_set(int gain) //BASS
{
    wait_eq_set_done();
    music_set_eq_for_aucar(8, gain);
    music_set_eq_by_num(sys_cb.eq_mode);
}
void aucar_music_treble_set(int gain)  //TRE
{
    wait_eq_set_done();
    music_set_eq_for_aucar(9, gain);
    music_set_eq_by_num(sys_cb.eq_mode);
}

u32 eq_add_gain(u32 dig_vol, u32 add_gain)      //GAIN_DIG_P7DB
{
    return (dig_vol * add_gain) >> 13;    //add_gain 8191(2^13) 0DB
}

void digital_vol_set_for_aucar(u32 dig_vol)
{
    wait_eq_set_done();
    //if (FUNC_FMRX == func_cb.sta) {
    //    dig_vol = eq_add_gain(dig_vol,GAIN_DIG_P7DB);  //FMRX 音量偏小，这里再增加7DB
    //}
    music_set_eq_gain(dig_vol);
    music_set_eq_by_num(sys_cb.eq_mode);
}
#endif

/*
//测试代码
void test_bass_treb_up(void);
void test_bass_treb_down(void);
static int bass_treb = 0;
void test_bass_treb_up(void)
{
    if (++bass_treb > 12) {
        bass_treb = 12;
    }
    printf("bass_treb = %d\n",bass_treb);
    music_set_eq_for_index(3,bass_treb);
    //music_bass_treble_eq_set(EQ_TREB,bass_treb);
    //music_bass_treble_eq_set(EQ_BASS,bass_treb);

    //aucar_music_bass_set(bass_treb);
    //aucar_music_treble_set(bass_treb);
    //aucar_music_loud_set(bass_treb);
}

void test_bass_treb_down(void)
{
    if (--bass_treb < -12) {
        bass_treb = -12;
    }
    printf("bass_treb = %d\n",bass_treb);
     music_set_eq_for_index(3,bass_treb);
    //music_bass_treble_eq_set(EQ_TREB,bass_treb);
    //music_bass_treble_eq_set(EQ_BASS,bass_treb);
    //aucar_music_bass_set(bass_treb);
    //aucar_music_treble_set(bass_treb);
    //aucar_music_loud_set(bass_treb);
}
*/

bool is_dac_soft_eq_dual_en(void)
{
    return DAC_SOFT_EQ_DUAL_EN;
}


//-------------------------------------------------
//EQ设置数据导出
#if  0   //EQ_INFO_DUMP
enum EQDUMP_TYPE {
    EQDUMP_GAIN0 = 0,
    EQDUMP_GAIN1 = 1,
    EQDUMP_EXTBL = 2,
    EQDUMP_RESTBL = 3,
    EQDUMP_DEFAULT = 4 ,
    EQDUMP_MAX,
};

const char *eqdump_type[] = {
   "Gain0:",
   "Gain1:",
   "ExtTbl:",
   "ResTbl:",
   "Default:"
};

//设置EQ时,导出实际EQ设置的数据,客户经常提在线调EQ和最终整合的资源EQ不一致。这里导出数据进行对比,MIC_EQ和DAC_EQ均可导出
void eq_info_dump(u8 type, u32 val)
{
    static u32 cnt = 0;
    static u32 last_type = 0;
    if (EQDUMP_GAIN0 == type) {
        my_printf("\nEQ info dump:\n");
        my_printf("Gain0: 0x%X\n", val);
        cnt = 0;
    } else if(1 == type) {
        my_printf("Gain1: 0x%X\n", val);
        cnt = 0;
    } else {
        if (last_type != type) {
            last_type = type;
            if (type < EQDUMP_MAX) {
                my_printf("type:%s\n",eqdump_type[type]);
            }
        }
        cnt++;
        my_printf("%X ",val);
        if (cnt % 5 == 0) {
            printf("\n");
        }
    }
}
#endif // EQ_INFO_DUMP'
//-------------------------------------------------
#if LOWPASS_BASSBOOST_PHASE180_EN
void low_high_pass_coef_cal_do(u8 index, int *coef, struct eq_coef_tbl_t *tbl, u8 flag);
int music_coef[16];
struct eq_coef_tbl_t bass_coef_tbl_customer[2];
struct eq_coef_tbl_t pass_coef_tbl_customer[2]; //high pass or low pass
//input band 0~9: 50.0  60.0  70.0  80.0  90.0  100.0  110.0  120.0  130.0
//QFactor = 0.750000
const int tbl_coef_bypass_1[10] = {
	CAL_FIX(0.9999746259),    //Band:0(50.000Hz)
	CAL_FIX(0.9999634614),    //Band:1(60.000Hz)
	CAL_FIX(0.9999502670),    //Band:2(70.000Hz)
	CAL_FIX(0.9999350427),    //Band:3(80.000Hz)
	CAL_FIX(0.9999177887),    //Band:4(90.000Hz)
	CAL_FIX(0.9998985049),    //Band:5(100.000Hz)
	CAL_FIX(0.9998771913),    //Band:6(110.000Hz)
	CAL_FIX(0.9998538481),    //Band:7(120.000Hz)
	CAL_FIX(0.9998284752),    //Band:8(130.000Hz)
//	CAL_FIX(0.9997716408),    //Band:9(150.000Hz)
	CAL_FIX(0.9898674722),    //Band:10 (TREB:1000.000Hz)
};

//Q:0.750000
const int tbl_coef_bypass_0[10] = {
	CAL_FIX(0.0047491552),    //Band:0(50.000Hz)
	CAL_FIX(0.0056989650),    //Band:1(60.000Hz)
	CAL_FIX(0.0066487633),    //Band:2(70.000Hz)
	CAL_FIX(0.0075985481),    //Band:3(80.000Hz)
	CAL_FIX(0.0085483174),    //Band:4(90.000Hz)
	CAL_FIX(0.0094980694),    //Band:5(100.000Hz)
	CAL_FIX(0.0104478021),    //Band:6(110.000Hz)
	CAL_FIX(0.0113975136),    //Band:7(120.000Hz)
	CAL_FIX(0.0123472020),    //Band:8(130.000Hz)
//	CAL_FIX(0.0142465016),    //Band:9(150.000Hz)
	CAL_FIX(0.0946628813),    //Band:10 (TREB:1000.000Hz)
};
//input band 0~9: 50.0  80.0  100.0  200.0  300.0  400.0  500.0  600.0  800.0
//QFactor = 0.750000
const int tbl_coef_bass_boost_1[10] = {
	CAL_FIX(0.9999746259),    //Band:0(50.000Hz)
	CAL_FIX(0.9999350427),    //Band:1(80.000Hz)
	CAL_FIX(0.9998985049),    //Band:2(100.000Hz)
	CAL_FIX(0.9995940400),    //Band:3(200.000Hz)
	CAL_FIX(0.9990866674),    //Band:4(300.000Hz)
	CAL_FIX(0.9983764898),    //Band:5(400.000Hz)
	CAL_FIX(0.9974636515),    //Band:6(500.000Hz)
	CAL_FIX(0.9963483378),    //Band:7 (or LOUD:600.000Hz)
	CAL_FIX(0.9935112308),    //Band:8 (BASS:800.000Hz)
	CAL_FIX(0.9898674722),    //Band:9 (TREB:1000.000Hz)
};

//Q:0.750000
const int tbl_coef_bass_boost_0[10] = {
	CAL_FIX(0.0047491552),    //Band:0(50.000Hz)
	CAL_FIX(0.0075985481),    //Band:1(80.000Hz)
	CAL_FIX(0.0094980694),    //Band:2(100.000Hz)
	CAL_FIX(0.0189942108),    //Band:3(200.000Hz)
	CAL_FIX(0.0284864965),    //Band:4(300.000Hz)
	CAL_FIX(0.0379729998),    //Band:5(400.000Hz)
	CAL_FIX(0.0474517949),    //Band:6(500.000Hz)
	CAL_FIX(0.0569209578),    //Band:7 (or LOUD:600.000Hz)
	CAL_FIX(0.0758227005),    //Band:8 (BASS:800.000Hz)
	CAL_FIX(0.0946628813),    //Band:9 (TREB:1000.000Hz)
};

void music_shelf_set(int gain, u8 freq)      //gain [-24,+24] freq [1,10],跟music_bassboost_set无法同时使用
{
    my_printf("music_shelf_set gain:%d, freq:%d\n", gain, freq);

    bass_coef_tbl_customer->coef_0 = &tbl_coef_bass_boost_0[freq-1];
    bass_coef_tbl_customer->coef_1 = &tbl_coef_bass_boost_1[freq-1];
    bass_treble_coef_cal_freq(&music_coef[1], gain, 0, bass_coef_tbl_customer);
    music_bassboost_coef_set((u32 *)&music_coef[1]);        //借用bassbost的eq路来做shelf，所以bssbost和shelf二选一
    music_set_eq_by_num(sys_cb.eq_mode);
}

void music_bassboost_set(int gain, u8 freq)      //gain [-24,+24] freq [1,10]，也就是peak
{
    my_printf("music_bassboost_set gain:%d, freq:%d\n", gain, freq);

    bass_coef_tbl_customer->coef_0 = &tbl_coef_bass_boost_0[freq-1];
    bass_coef_tbl_customer->coef_1 = &tbl_coef_bass_boost_1[freq-1];
    eq_coef_cal(0, &music_coef[1], gain, bass_coef_tbl_customer);
    music_bassboost_coef_set((u32 *)&music_coef[1]);
    music_set_eq_by_num(sys_cb.eq_mode);
}

void music_low_high_pass(u8 freq, u8 flag)
{
    //flag = 0->lowpass, flag = 1 -> highpass
    my_printf("music_low_hight_pass %s: freq:%d\n", (flag)? "highpass" : "lowpass", freq);

    pass_coef_tbl_customer->coef_0 = &tbl_coef_bypass_0[freq-1];
    pass_coef_tbl_customer->coef_1 = &tbl_coef_bypass_1[freq-1];
    low_high_pass_coef_cal_do(0, &music_coef[6], pass_coef_tbl_customer, flag);
    music_lowhigh_pass_coef_set((u32 *)&music_coef[6]);
    music_set_eq_by_num(sys_cb.eq_mode);
}
void music_low_high_pass_extend(u8 freq, u8 flag)                   //扩展高低通，使用EQ的5-6段
{
    //flag = 0->lowpass, flag = 1 -> highpass
    my_printf("music_low_high_pass_extend %s: freq:%d\n", (flag)? "highpass" : "lowpass", freq);

    pass_coef_tbl_customer->coef_0 = &tbl_coef_bypass_0[freq-1];
    pass_coef_tbl_customer->coef_1 = &tbl_coef_bypass_1[freq-1];
    low_high_pass_coef_cal_do(0, &music_coef[11], pass_coef_tbl_customer, flag);
    music_lowhigh_pass_ext_coef_set((u32 *)&music_coef[11]);
    music_set_eq_by_num(sys_cb.eq_mode);
}

#endif

void bsp_eq_init(void)
{
#if SYS_BASS_TREBLE_EN
    bsp_bass_treble_init();
#endif

#if MIC_LOUD_EN
    mic_eq_loud_init();
#endif // MIC_LOUD_EN

#if MIC_BASS_TREBLE_EN
    mic_bass_treble_init();
#endif

#if AUCAR_EQ_LOUD_BASS_TREBLE_EN
    aucar_eq_loud_bass_tre_init();
#endif

#if SYS_EQ_FOR_IDX_EN || DAC_SOFT_EQ_DUAL_EN
    sys_eq_for_idx_init();
#endif

#if MIC_EQ_FOR_IDX_EN
    mic_eq_for_idx_init();
#endif
}

#if LOWHIGH_PASS_EN
void low_high_pass_coef_cal_do(u8 index, int *coef, struct eq_coef_tbl_t *tbl, u8 flag);
void eq_low_high_set(int *lp_coef, u8 lp_slope, int *hp_coef, u8 hp_slope);
const int tbl_lp_1[8] = {
    CAL_FIX(0.9999350427), //Band0, Qfactor(0.750), (80Hz)
    CAL_FIX(0.9998985049), //Band1, Qfactor(0.750), (100Hz)
    CAL_FIX(0.9998538481), //Band2, Qfactor(0.750), (120Hz)
    CAL_FIX(0.9997716408), //Band3, Qfactor(0.750), (150Hz)
    CAL_FIX(0.9996711682), //Band4, Qfactor(0.750), (180Hz)
    CAL_FIX(0.9995940400), //Band5, Qfactor(0.750), (200Hz)
    CAL_FIX(0.9995087954), //Band6, Qfactor(0.750), (220Hz)
    CAL_FIX(0.9993657117), //Band7, Qfactor(0.750), (250Hz)
};
const int tbl_lp_0[8] = {
    CAL_FIX(0.0075985481), //Band0, Qfactor(0.750), (80Hz)
    CAL_FIX(0.0094980694), //Band1, Qfactor(0.750), (100Hz)
    CAL_FIX(0.0113975136), //Band2, Qfactor(0.750), (120Hz)
    CAL_FIX(0.0142465016), //Band3, Qfactor(0.750), (150Hz)
    CAL_FIX(0.0170952293), //Band4, Qfactor(0.750), (180Hz)
    CAL_FIX(0.0189942108), //Band5, Qfactor(0.750), (200Hz)
    CAL_FIX(0.0208930381), //Band6, Qfactor(0.750), (220Hz)
    CAL_FIX(0.0237409561), //Band7, Qfactor(0.750), (250Hz)
};

const int tbl_hp_1[8] = {
    CAL_FIX(0.9999959401), //Band0, Qfactor(0.750), (20Hz)
    CAL_FIX(0.9999837605), //Band1, Qfactor(0.750), (40Hz)
    CAL_FIX(0.9999634614), //Band2, Qfactor(0.750), (60Hz)
    CAL_FIX(0.9999350427), //Band3, Qfactor(0.750), (80Hz)
    CAL_FIX(0.9998985049), //Band4, Qfactor(0.750), (100Hz)
    CAL_FIX(0.9998538481), //Band5, Qfactor(0.750), (120Hz)
    CAL_FIX(0.9998010728), //Band6, Qfactor(0.750), (140Hz)
    CAL_FIX(0.9997401793), //Band7, Qfactor(0.750), (160Hz)
};
const int tbl_hp_0[8] = {
    CAL_FIX(0.0018996756), //Band0, Qfactor(0.750), (20Hz)
    CAL_FIX(0.0037993357), //Band1, Qfactor(0.750), (40Hz)
    CAL_FIX(0.0056989650), //Band2, Qfactor(0.750), (60Hz)
    CAL_FIX(0.0075985481), //Band3, Qfactor(0.750), (80Hz)
    CAL_FIX(0.0094980694), //Band4, Qfactor(0.750), (100Hz)
    CAL_FIX(0.0113975136), //Band5, Qfactor(0.750), (120Hz)
    CAL_FIX(0.0132968653), //Band6, Qfactor(0.750), (140Hz)
    CAL_FIX(0.0151961090), //Band7, Qfactor(0.750), (160Hz)
};

int eq_lp_coef[5];
int eq_hp_coef[5];
struct eq_coef_tbl_t eq_coef_tbl_customer[2]; //high pass or low pass

void eq_low_high_pass(u8 freq, u8 flag)
{
    //flag = 0->lowpass, flag = 1 -> highpass
//    my_printf("music_low_hight_pass %s: freq:%d\n", (flag)? "highpass" : "lowpass", freq);

    if (flag) {
        eq_coef_tbl_customer->coef_0 = &tbl_hp_0[freq-1];
        eq_coef_tbl_customer->coef_1 = &tbl_hp_1[freq-1];
        low_high_pass_coef_cal_do(0, &eq_hp_coef[0], eq_coef_tbl_customer, flag);
    }   else {
        eq_coef_tbl_customer->coef_0 = &tbl_lp_0[freq-1];
        eq_coef_tbl_customer->coef_1 = &tbl_lp_1[freq-1];
        low_high_pass_coef_cal_do(0, &eq_lp_coef[0], eq_coef_tbl_customer, flag);
    }
}

void bsp_lowhigh_pass_set(u8 lp_fre, u8 lp_slope, u8 hp_fre, u8 hp_slope)
{
    eq_low_high_pass(lp_fre, 0);
    eq_low_high_pass(hp_fre, 1);
    lp_slope = (lp_slope>4)?4:lp_slope;
    hp_slope = (hp_slope>4)?4:hp_slope;
    eq_low_high_set(&eq_lp_coef[0], lp_slope, &eq_hp_coef[0], hp_slope);
}
#endif
